import { defineComponent, h, inject, watchEffect, ref, nextTick } from 'vue'
import type { questionSideListState, diyRuleState } from '@/types/baseConfig'
import type { PropType, Ref } from 'vue'
import type { addRuleState } from '@/types/form'
import type { FormInst, DataTableColumns } from 'naive-ui'
import { getWayName } from '@/enum/wayEnum'
import { nanoid } from 'nanoid'
import pageStyle from '../../styles/rule.module.scss'
import questionOption from '@/basic/addEdit/questionsOption'
import ruleTriggerEnum from '@/enum/ruleTriggerEnum'
import validateEnum from '@/enum/validateEnum'
import RuleTest from './RuleTest'
import ADDParams from './ADDParams'
import MessageBox from '@/components/nComponents/MessageBox'
import {
  NCollapse,
  NCollapseItem,
  NSwitch,
  NInput,
  NSelect,
  NDataTable,
  NButton,
  NDropdown,
  NForm,
  NFormItem,
  NEmpty
} from 'naive-ui'
export default defineComponent({
  props: {
    compData: {
      type: Object as PropType<questionSideListState>,
      default: () => {
        return {}
      }
    }
  },
  emits: ['save'],
  setup: function (props, { emit }) {
    const $clone = inject('$clone') as <T>(data: T) => T
    const info = ref<questionSideListState>(questionOption)
    watchEffect(() => {
      if (props.compData) {
        info.value = $clone(props.compData)
      }
    })

    /**
     *  正则测试验证
     * */
    const ruleRef = ref()
    const handTestRule = () => {
      if (info.value?.ruleInfo) {
        ruleRef.value.open(info.value.ruleInfo.regex)
      }
    }

    /**
     *  添加rule表格
     * */
    const addShow = ref(false)
    const messageBoxTitle = ref('添加条件')
    const formRef = ref<FormInst | null>(null)
    const formValue: any = ref({
      name: ''
    })
    const rules = {
      name: {
        required: true,
        message: '请输入备注',
        trigger: 'blur'
      }
    }
    const handSave = () => {
      formRef.value?.validate(errors => {
        if (!errors) {
          if (!info.value?.ruleInfo) return
          if (formValue.value.uid) {
            const index = info.value.ruleInfo.diyRule.findIndex(
              (el: diyRuleState) => el.uid === formValue.value.uid
            )
            if (index >= 0) {
              info.value.ruleInfo.diyRule[index] = formValue.value
            }
          } else {
            info.value.ruleInfo.diyRule.push({
              name: formValue.value.name,
              uid: nanoid(),
              childer: []
            })
          }
          handOptions()
          addShow.value = false
        }
      })
    }
    const handAddZu = (e?: any) => {
      if (e) {
        messageBoxTitle.value = '编辑自定义规则'
        formValue.value = $clone(e)
      } else {
        messageBoxTitle.value = '添加自定义规则'
        formValue.value = {
          name: ''
        }
      }
      addShow.value = true
    }

    let talbeIndex = -1
    let oldIndex = 0
    const addRef = ref()
    const paramsSave = (e: addRuleState) => {
      if (!info.value?.ruleInfo) return
      if (talbeIndex === -1) {
        info.value.ruleInfo.diyRule[oldIndex].childer.push(e)
      } else {
        info.value.ruleInfo.diyRule[oldIndex].childer[talbeIndex] = e
      }
      handOptions()
    }
    /**
     *  添加rule条件
     * */
    const handAddRuleRow = (index: number) => {
      talbeIndex = -1
      oldIndex = index
      addRef.value.open()
    }

    const x = ref(0)
    const y = ref(0)
    const handDel = (index: number) => {
      if (!info.value?.ruleInfo) return
      info.value.ruleInfo.diyRule.splice(index, 1)
      handOptions()
    }
    const showDropdown = ref(false)
    const options = [
      {
        label: '编辑',
        key: 'edit'
      },
      {
        label: () => h('span', { style: { color: 'red' } }, '删除'),
        key: 'delete'
      }
    ]
    const handleSelect = (e: string) => {
      if (!info.value?.ruleInfo) return
      const showRuleInfo = info.value.ruleInfo.diyRule[oldIndex]
      const rowInfo = showRuleInfo.childer[talbeIndex]
      if (e === 'edit') {
        addRef.value.open($clone(rowInfo))
      } else if (e === 'delete') {
        info.value.ruleInfo.diyRule[oldIndex].childer.splice(talbeIndex, 1)
      }
      showDropdown.value = false
    }
    const rowProps = (rowData: diyRuleState, rowIndex: number, index: number) => {
      return {
        onContextmenu: (e: any) => {
          talbeIndex = rowIndex
          oldIndex = index
          e.preventDefault()
          showDropdown.value = false
          nextTick(() => {
            showDropdown.value = true
            x.value = e.clientX
            y.value = e.clientY
          })
        }
      }
    }
    /**
     *  展示条件表格columns
     * */
    const questions = inject('questions') as Ref<questionSideListState[]>
    const getName = (key: string) => {
      let name = ''
      try {
        const getChilder = (arr: questionSideListState[]) => {
          arr.forEach((el: questionSideListState) => {
            if (el.commonForm.labelKey === key) {
              throw new Error(el.commonForm.labelName)
            }
            if (el?.RowLayoutForm) {
              if (el.RowLayoutForm.childer && el.RowLayoutForm.childer.length > 0) {
                getChilder(el.RowLayoutForm.childer)
              }
            }
          })
        }
        questions.value.forEach((el: questionSideListState) => {
          if (el.commonForm.labelKey === key) {
            throw new Error(el.commonForm.labelName)
          }
          if (el?.RowLayoutForm) {
            if (el.RowLayoutForm.childer && el.RowLayoutForm.childer.length > 0) {
              getChilder(el.RowLayoutForm.childer)
            }
          }
        })
      } catch (e: any) {
        name = e.message
      }
      return '[本表]' + name || key
    }

    const columns: DataTableColumns = [
      {
        title: '判断条件',
        key: 'way',
        render(row: any) {
          return [
            h(
              'span',
              {},
              {
                default: () => getWayName(row.way)
              }
            )
          ]
        }
      },
      {
        title: '值/key',
        key: 'value',
        render(row: any) {
          return [
            h(
              'span',
              {},
              {
                default: () => (row.isItem ? getName(row.labelKey) : row.value)
              }
            )
          ]
        }
      }
    ]
    /**
     *  变化回调
     * */
    let timer: any = null
    const handOptions = () => {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }
      timer = setTimeout(() => {
        clearTimeout(timer)
        timer = null
        emit('save', info.value)
      }, 450)
    }
    return () => (
      <div class={pageStyle.editRule}>
        {info.value?.ruleInfo ? (
          <>
            {' '}
            <NCollapse
              accordion
              class="group w-full"
              arrow-placement="right"
              default-expanded-names={['ruleInfo']}
            >
              <NCollapseItem name="ruleInfo">
                {{
                  header: () => (
                    <div class="cell">
                      <div class="title u-line-1">规则验证</div>
                    </div>
                  ),
                  default: () => (
                    <>
                      {info.value.ruleInfo && (
                        <>
                          <div class="mt-[20px] flex items-center">
                            <div class="settingItemTitle">是否开启</div>
                            <div class="flex-1 ml-[5px]">
                              <NSwitch
                                v-model:value={info.value.ruleInfo.isRules}
                                onUpdateValue={handOptions}
                              />
                            </div>
                          </div>
                          {info.value.ruleInfo.isRules && (
                            <>
                              <div class="mt-[20px] flex items-center">
                                <div class="settingItemTitle">是否必填</div>
                                <div class="flex-1 ml-[5px]">
                                  <NSwitch
                                    v-model:value={info.value.ruleInfo.isRequired}
                                    onUpdateValue={handOptions}
                                  />
                                </div>
                              </div>
                              <div class="mt-[20px]">
                                <div class="settingItemTitle">必填校验提示</div>
                                <div class="edit-input">
                                  <NInput
                                    v-model:value={info.value.ruleInfo.requiredTip}
                                    placeholder="请输入"
                                    clearable
                                    onBlur={handOptions}
                                  />
                                </div>
                              </div>
                              <div class="mt-[20px]">
                                <div class="settingItemTitle">触发时机</div>
                                <div class="edit-input">
                                  <NSelect
                                    v-model:value={info.value.ruleInfo.trigger}
                                    placeholder="请选择"
                                    clearable
                                    options={ruleTriggerEnum}
                                    onUpdateValue={handOptions}
                                  />
                                </div>
                              </div>
                              <div class="mt-[20px]">
                                <div class="settingItemTitle">正则</div>
                                <div class="edit-input">
                                  <NSelect
                                    v-model:value={info.value.ruleInfo.regex}
                                    filterable
                                    tag
                                    placeholder="请输入或者选择"
                                    clearable
                                    options={validateEnum}
                                    onUpdateValue={handOptions}
                                  />
                                </div>
                              </div>
                              {info.value.ruleInfo.regex && (
                                <>
                                  <div
                                    class="tip mt10 flex justify-end cursor-pointer"
                                    onClick={handTestRule}
                                  >
                                    <span class="validateEnum">测试</span>
                                  </div>
                                  <div class="mt-[10px]">
                                    <div class="settingItemTitle">校验失败提示</div>
                                    <div class="edit-input">
                                      <NInput
                                        v-model:value={info.value.ruleInfo.regexTip}
                                        placeholder="请输入"
                                        clearable
                                        onBlur={handOptions}
                                      />
                                    </div>
                                  </div>
                                </>
                              )}
                            </>
                          )}
                        </>
                      )}
                    </>
                  )
                }}
              </NCollapseItem>
              {info.value?.ruleInfo &&
                info.value.ruleInfo.diyRule.map((item: diyRuleState, index: number) => (
                  <>
                    <NCollapseItem name={item.uid}>
                      {{
                        header: () => (
                          <div class="cell">
                            <div class="title u-line-1">{item.name}</div>
                          </div>
                        ),
                        default: () => (
                          <>
                            <NDataTable
                              class="mt-[20px]"
                              columns={columns}
                              data={item.childer}
                              row-props={(rowData: diyRuleState, rowIndex: number) => {
                                return rowProps(rowData, rowIndex, index)
                              }}
                            />
                            <div class="mt-[10px] flex justify-end">
                              <NButton round type="warning" onClick={() => handAddRuleRow(index)}>
                                <span>新增</span>
                              </NButton>
                              <NButton
                                style={{ marginLeft: '10px' }}
                                round
                                type="error"
                                onClick={() => handDel(index)}
                              >
                                <span>删除</span>
                              </NButton>
                            </div>
                          </>
                        )
                      }}
                    </NCollapseItem>
                  </>
                ))}
              <div class="mt-[10px]">
                <NButton style={{ width: '100%' }} onClick={() => handAddZu()}>
                  <span>新增自定义规则</span>
                </NButton>
              </div>
            </NCollapse>
            <NDropdown
              placement="bottom-start"
              trigger="manual"
              x={x.value}
              y={y.value}
              options={options}
              show={showDropdown.value}
              onSelect={handleSelect}
            />
            <RuleTest ref={ruleRef} />
            <ADDParams ref={addRef} onSave={paramsSave} />
            <MessageBox v-model={addShow.value} title={messageBoxTitle.value} isClose>
              <>
                <NForm ref={formRef} label-width={80} model={formValue.value} rules={rules}>
                  <NFormItem label="备注" path="name">
                    <NInput v-model:value={formValue.value.name} placeholder="请输入备注" />
                  </NFormItem>
                </NForm>
                <div class="btns flex align-center justify-end">
                  <NButton
                    onClick={() => {
                      addShow.value = false
                    }}
                  >
                    取消
                  </NButton>
                  <NButton style={{ marginLeft: '10px' }} type="primary" onClick={handSave}>
                    提交
                  </NButton>
                </div>
              </>
            </MessageBox>
          </>
        ) : (
          <NEmpty description="此组件无需规则验证" />
        )}
      </div>
    )
  }
})
